package com.twq.basic.bigpicture

/**
 * Created by tangweiqun on 2017/11/27.
 * 使用类型参数化的数组Array
 */
object Step7 {
  def main(args: Array[String]): Unit = {
    //参数化(Parameterization)
    //在scala中我们可以用值和类型来参数化初始化的对象，比如：
    //1、初始化BigInteger，并且用值"12345"来参数化这个初始化的对象
    //值参数，我们是写在()里
    val big = new java.math.BigInteger("12345")

    //2、类型参数，我们是写在[]中，如下：
    //String就是对象greetStrings的类型参数
    val greetStrings = new Array[String](3)

    //3、greetStrings虽然是被val修饰，但是greetStrings引用的对象是可以被重新赋值的
    greetStrings(0) = "Hello" //被转换为greetStrings.update(0, "Hello")
    greetStrings(1) = ", "
    greetStrings(2) = "world!\n"
    //4、
    //0 to 2等于(0).to(2)，在scala中，如果一个方法只有一个参数，那么我们可以省略掉点和括号，比如Console println 2
    //0 to 2产生一个(0, 1, 2)的Seq
    for (i <- 0 to 2)
      print(greetStrings(i))

    //5、在scala中为什么用()来访问数组呢？
    //和java不一样的是，Scala中的Array也是一个类，当我们用()来访问一个Array的对象的时候，
    // 我们其实是调用Array中的apply方法，所以greetStrings(i)和greetStrings.apply(i)是一样的

    //所以，上面的例子可以改写成：
    greetStrings.update(0, "Hello")
    greetStrings.update(1, ", ")
    greetStrings.update(2, "world!\n")
    for (i <- 0.to(2))
      print(greetStrings.apply(i))

    //6、scala将所有的东西(从数组到表达式)都看作成带有方法的对象。所以你不需要记住特殊的类
    //java中你就要区分开基本类型和它们对应的包装类，数组和常规的对象。
    //scala这样做是不会影响scala的运行性能的，
    // 因为当碰到基本类型和数据的时候，scala的编译器会将scala的对象翻译成java的基本类型和数据

    //7、更简单的创建数组，包括类型推断
    val numNames = Array("zero", "one", "two")
    //上面的代码就相当于调用Array的静态方法apply
    val numNames2 = Array.apply("zero", "one", "two")

    //对于apply我们在将伴生对象的时候会详细讲述


    //8、变长数组：数组缓冲
    import scala.collection.mutable.ArrayBuffer
    val b = ArrayBuffer[Int]()
    //当然也可以通过new ArrayBuffer[Int]()来创建一个空的数组缓冲

    b += 1 //在尾端加一个元素
    b += (1, 2, 3, 4) //在尾端添加多个元素

    b -= 1

    b(1)
    b.foreach(println)
  }
}
